package com.coment.game.fight;

import com.coment.cfg.luban.Tables;
import com.coment.cfg.luban.roles.NumericalConfig;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/// 属性
public class Attrs extends HashMap<Integer, Double> {
    /// 属性默认值
    public static final Map<Integer, Double> ATTR_DEFAULT_VALUE = new ConcurrentHashMap<>();
    /// 属性数值类型
    public static final Map<Integer, Integer> NUMBER_TYPE = new ConcurrentHashMap<>();
    public static final Map<Integer, Integer> NUMBER_E_TYPE = new ConcurrentHashMap<>();

    static {
        for (NumericalConfig numericalConfig : Tables.cfg.get_tbnumericalconfig().getDataList()) {
            NUMBER_E_TYPE.put(numericalConfig.NumericalID, numericalConfig.effectType);

            // 属性对应类型
            NUMBER_TYPE.put(numericalConfig.NumericalID, numericalConfig.NumType);
            // 属性默认值
            ATTR_DEFAULT_VALUE.put(numericalConfig.NumericalID, numericalConfig.InitialValue / numericalConfig.NumType);
        }
    }

    public Attrs() {
        super();
    }

    public Attrs(Map<Integer, Double> attribute) {
        putAll(attribute);
    }

    /// 获取属性值-包含默认值
    @Override
    public Double get(Object key) {
        return Math.ceil(super.getOrDefault(key, ATTR_DEFAULT_VALUE.get(key)) * 100) / 100;
    }

    /// 获取指定类型的属性
    public Attrs obtainByType(int... typeParms) {
        Attrs attrs = new Attrs();
        if (typeParms == null || typeParms.length == 0) {
            return attrs;
        }

        Set<Integer> typeSet = new HashSet<>();
        for (int t : typeParms) {
            typeSet.add(t);
        }

        this.forEach((k, v) -> {
            Integer type = NUMBER_E_TYPE.get(k);
            if (typeSet.contains(type)) {
                attrs.put(k, v);
            }
        });
        return attrs;
    }

    /**
     * 属性更新
     *
     * @param b 属性更新值
     */
    public Attrs update(Attrs b) {
        b.forEach((key, value) -> this.merge(key, value, Double::sum));
        return this;
    }

    public boolean hasValue() {
        return this.values().stream().noneMatch(x -> x == 0);
    }
}
